package com.huasan.www.demon.rest.resource;

import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.glassfish.jersey.server.mvc.Viewable;

import com.huasan.www.demon.pojo.Userinfo;
import com.huasan.www.demon.rest.util.Constants;

public abstract class Resource {

	protected final Logger logger = Logger.getLogger(this.getClass());
	
	protected Map<String,Object> mapParams = new HashMap<String,Object>();
	
	@Context
	Request request;
	
	@Context
	HttpServletRequest httpServletRequest;
	
	@Context
	HttpServletResponse httpServletResponse;
	
	@Context
	HttpHeaders httpHeaders;
	
	@Context
	protected UriInfo uri;
	
	protected ObjectMapper objectmapper = new ObjectMapper();
	
	private JsonConfig config = new JsonConfig();   
	
	protected <T> Map<String,T> setParams(T object) {
		if (object == null){
			return (Map<String, T>) mapParams;
		}
		
		Map<String,Object> retMap = new HashMap<String,Object>();
		retMap.putAll(mapParams);
		
		if (object instanceof Map){
			retMap.putAll((Map<String, T>) object);
			return (Map<String, T>) retMap;
		}
		
		Method[] methods = object.getClass().getMethods();
		List methodNames = getLowerName(methods, 3);
		
		Field[] fields = object.getClass().getDeclaredFields();
		for (Field field : fields){
			try {
				if (methodNames.contains(field.getName().toLowerCase())){
					field.setAccessible(true);
					Object value = field.get(object);
					if (isArray(value)){
						JSONArray jsonArray = JSONArray.fromObject(value);
						retMap.put(field.getName(), jsonArray);
					} else if (value instanceof String){
						retMap.put(field.getName(), value);
					}else {
						JSONObject jsonObject = JSONObject.fromObject(value);
						retMap.put(field.getName(), jsonObject);
					}
				}
			} catch (IllegalArgumentException e) {
				logger.error(e);
			} catch (IllegalAccessException e) {
				logger.error(e);
			}
		}
		return (Map<String, T>) retMap;
	}
	
	private List<String> getLowerName( Member[] objects, Integer begin ){
		if (begin == null)
			begin = 0;
		List<String> names = new ArrayList<String>();
		for (Member object : objects){
			names.add(object.getName().substring(begin).toLowerCase());
		}
		return names;
	}
	
	private boolean isArray(Object obj){
		if (obj instanceof Object[])
			return true;
		if (obj instanceof List || obj instanceof Map || obj instanceof Set)
			return true;
		return false;
	}
	
	protected Viewable getView(String viewName, Object object) {
		return new Viewable(getView(viewName), setParams(object));
	}
	
	protected Viewable getView(String viewName, Object object, Map map) {
		map.putAll(setParams(object));
		return new Viewable(getView(viewName), map);
	}
	
	protected final String getView(String viewname){
		return Constants.VIEWPATH + viewname;
	}
	
	protected Response getResponse(String jsonData){
		return Response.ok(jsonData).header("Content-Type", "application/json;charset=UTF-8").build();
	}
	
	protected Response getResponse(String jsonData, String header){
		return Response.ok(jsonData).header("Content-Type", header).build();
	}
	
	protected Response getResponse(int status, String jsonData, String header){
		return Response.status(status).entity(jsonData).header("Content-Type", header).build();
	}
	
	protected Response getResponse(int status, String jsonData){
		return Response.status(status).entity(jsonData).header("Content-Type", "application/json;charset=UTF-8").build();
	}
	
	public String getSucReturn(String data, String msg){
		return Constants.JSON_TEMPLATE.replace("{0}", "\"ok\"").
						replace("{1}", data).replace("{2}", msg);
	}
	
	public String getSucReturn(String msg){
		return Constants.JSON_TEMPLATE.replace("{0}", "\"ok\"").
						replace("{1}", "\"\"").replace("{2}", msg);
	}
	
	public String getErrReturn(String msg){
		return Constants.JSON_TEMPLATE.replace("{0}", "\"err\"").
						replace("{1}", "\"\"").replace("{2}", msg);
	}
	
	public Map<String,String> getCallBack(String status, String msg, String fileName){
		Map<String,String> map = new HashMap<String,String>();
		map.put("status", status);
		map.put("msg", msg);
		map.put("filename", fileName);
		return map;
	}
	
	protected void setSession(Userinfo user){
		httpServletRequest.getSession().setAttribute("userinfo", user);
	}
	
}
